package com.yanfan.njLighting.utils;

import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

public class ModbusQuery {

    /**
     * 发送自定义的 Modbus 查询指令，并返回响应数据
     *
     * @param ip Modbus 服务器 IP 地址
     * @param port Modbus TCP 端口
     * @param command 发送的 Modbus 查询指令
     * @return 返回从服务器接收的响应数据
     * @throws Exception 出现连接或读取错误时抛出异常
     */
    public static byte[] sendModbusQuery(String ip, int port, byte[] command) throws Exception {
        byte[] response = new byte[256];  // 假设最大响应数据不超过 256 字节

        try (Socket socket = new Socket(ip, port);
             OutputStream out = socket.getOutputStream();
             InputStream in = socket.getInputStream()) {

            // 发送 Modbus 查询指令
            out.write(command);
            out.flush();
            System.out.println("已发送 Modbus 查询指令至服务器。");

            // 读取响应数据
            int length = in.read(response);  // 读取实际的响应长度

            if (length == -1) {
                throw new Exception("未收到服务器响应，连接可能已关闭。");
            }

            // 截取有效的响应数据
            byte[] trimmedResponse = new byte[length];
            System.arraycopy(response, 0, trimmedResponse, 0, length);

            return trimmedResponse;

        } catch (Exception e) {
            System.err.println("与 Modbus 服务器通信失败：" + e.getMessage());
            throw e;
        }
    }

    public static void main(String[] args) {
        String ip = "192.168.23.201";  // Modbus 服务器 IP
        int port = 502;  // Modbus TCP 端口

        // 构造 Modbus 查询命令
        byte[] command = new byte[]{
                0x12, 0x54,         // 事务处理标识符
                0x00, 0x00,         // 协议标识符
                0x00, 0x06,         // 数据总长度
                0x01,               // RTU地址
                0x03,               // 功能码（0x03 表示读取保持寄存器）
                (byte) 0x9C, 0x40,  // 起始地址 40000
                0x00, 0x02          // 寄存器数量（读取 2 个寄存器）
        };

        try {
            // 发送查询指令并接收响应
            byte[] response = sendModbusQuery(ip, port, command);
            System.out.println("已接收到服务器的响应数据：");

            // 打印响应数据（十六进制格式）
            for (byte b : response) {
                System.out.printf("0x%02X ", b);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
